<template>
    <view class="upload-container">
        <u-upload :previewImage="true" :max-count="maxCount" :auto-upload="false" @afterRead="handleAfterRead"
            @beforeRead="handleBeforeRead" :useBeforeRead="true" @delete="handleDelete" :multiple="multiple"
            :accept="accept" :fileList="fileList">
            <slot name="file"></slot>
        </u-upload>
    </view>
</template>

<script>
import { getToken, tempFilePathToFile, compressFile } from "@/utils";
import { uploadFile } from "@/utils/api";

export default {
    data() {
        return {
            fileList: [
                // {
                //     url: "/dev-api/profile/upload/2024/10/30/公司logo_20241030231031A009.jpg",
                // },
            ],
        };
    },
    props: {
        value: [String, Object, Array],
        maxCount: {
            type: Number,
            default: 1,
        },
        // 文件大小限制 M
        fileSize: {
            type: Number,
            default: 20,
        },
        fileType: {
            type: Array,
            default: () => ["jpg", "png", "jpeg"],
        },
        accept: {
            type: String,
            default: "image",
        },
        multiple: {
            type: Boolean,
            default: false,
        },
        //  是否压缩的阈值 单位M
        threshold: {
            type: Number,
            default: 1,
        },
    },
    watch: {
        value: {
            handler(val) {
                if (val) {
                    // 首先将值转为数组
                    const list = Array.isArray(val)
                        ? val
                        : this.value.split(",");
                    // 然后将数组转为对象数组
                    this.fileList = list.map((item) => {
                        if (typeof item === "string") {
                            let baseURL = this.globalVar.request.baseURL;
                            if (item.indexOf(baseURL) === -1) {
                                item = {
                                    name: baseURL + item,
                                    url: baseURL + item,
                                };
                            } else {
                                item = { name: item, url: item };
                            }
                        }
                        return item;
                    });
                } else {
                    this.fileList = [];
                    return [];
                }
            },
            deep: true,
            immediate: true,
        },
    },
    methods: {
        // uploadFilePromise(url) {
        //     return new Promise((resolve, reject) => {
        //         uni.uploadFile({
        //             url: `${this.globalVar.request.baseURL}/common/upload`, // 仅为示例，非真实的接口地址
        //             filePath: url,
        //             name: "file",
        //             header: {
        //                 Authorization: "Bearer " + getToken(),
        //             },
        //             success: (res) => {
        //                 setTimeout(() => {
        //                     resolve(JSON.parse(res.data));
        //                 }, 1000);
        //             },
        //         });
        //     });
        // },
        uploadFilePromise(file) {
            return new Promise(async (resolve, reject) => {
                try {
                    let formData = new FormData();
                    formData.append("file", file, file.name);
                    fetch(`${this.globalVar.request.baseURL}/common/upload`, {
                        method: "POST",
                        headers: {
                            Authorization: "Bearer " + getToken(),
                        },
                        body: formData,
                    })
                        .then((res) => res.json())
                        .then((res) => {
                            resolve(res);
                        });
                } catch (error) {
                    console.log(error);
                    resolve(null);
                }
            });
        },

        handleBeforeRead(e) {
            let files = typeof e.file === "object" ? [e.file] : e.file;
            let isLimitSize = files.some(
                (file) => file.size > this.fileSize * 1024 * 1024
            );
            if (isLimitSize) {
                this.$u.toast(`文件大小不能超过${this.fileSize}MB`);
                return false;
            }
            let isLimitType = files.some(
                (file) => !this.fileType.includes(file.name.split(".").pop())
            );
            if (isLimitType) {
                this.$u.toast(`仅支持${this.fileType.join(",")}格式`);
                return false;
            }
            return true;
        },

        async handleAfterRead(e) {
            let files = typeof e.file === "object" ? [e.file] : e.file;
            files.map((item) => {
                this.fileList.push({
                    ...item,
                    status: "uploading",
                    message: "上传中",
                });
            });
            let start = 0;
            for (let i = 0; i < files.length; i++) {
                let item = files[i];
                let file = await tempFilePathToFile({
                    tempFilePath: item.url,
                    fileName: item.name,
                });
                // 判断是否需要压缩
                if (file.size > this.threshold * 1024 * 1024) {
                    file = await compressFile(file, { quality: 0.2 });
                }
                let res = await this.uploadFilePromise(file);
                if (res.code == 200) {
                    this.fileList.splice(
                        start,
                        1,
                        Object.assign(item, {
                            status: "success",
                            message: "",
                            url: this.globalVar.request.baseURL + res.fileName,
                        })
                    );
                } else {
                    this.fileList.splice(
                        start,
                        1,
                        Object.assign(item, {
                            status: "error",
                            message: "上传失败",
                        })
                    );
                }
                start++;
            }
            this.$emit("input", this.listToString(this.fileList));
            let list = this.fileList.map((item) => {
                item.url = item.url.replace(this.globalVar.request.baseURL, "");
                return item;
            });
            this.$emit("change", list);
        },
        handleDelete(e) {
            this[`fileList`].splice(e.index, 1);
            this.$emit("input", this.listToString(this.fileList));
            // this.$emit("change", this.fileList);
        },
        // 对象转成指定字符串分隔
        listToString(list, separator) {
            let strs = "";
            separator = separator || ",";
            for (let i in list) {
                if (list[i].url) {
                    strs +=
                        list[i].url.replace(
                            this.globalVar.request.baseURL,
                            ""
                        ) + separator;
                }
            }
            return strs != "" ? strs.substr(0, strs.length - 1) : "";
        },
    },
};
</script>

<style scoped>
.upload-container {
    padding: 20px;
}

.upload-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dashed #d9d9d9;
    border-radius: 5px;
    padding: 20px;
    cursor: pointer;
}

.upload-file {
    position: relative;
    margin-top: 10px;
}

.upload-file image {
    border: 1px solid #d9d9d9;
    border-radius: 5px;
}

.upload-file .u-icon {
    position: absolute;
    top: 5px;
    right: 5px;
}
</style>